setvbuf関数は、ファイルの入出力を行うときのバッファリング方法を設定します。この関数は、次の3つのことを設定できます。
- バッファ領域
- バッファサイズ
- バッファリングモード
バッファリングモードには、データを書き込むとすぐに出力先ファイルに書き込むunbuffered、文字の読み書きはブロック単位でいっぺんに行うfully buffered、新しい行が出力されるか、新しい行が入力されるまで蓄えるline bufferedの3種類があります。
#include <stdio.h>
int setvbuf(FILE *stream, char *buf, int mode, size_t size);
*streamはfopen関数で取得した、ファイルポインタを指定します。
*bufは入出力を行うときに使用するバッファ領域を指定します。
modeはバッファリングの方法を指定します。
sizeはバッファの大きさをバイト単位で指定します。
戻り値として、正常に処理ができた場合は0を、失敗した場合は0以外を返します。
第2引数の*bufの大きさは、第4引数のsize以上必要です。また、NULLを指定した場合は、バッファリングモードだけを指定したことになります。なお、ここで指定した領域は、ファイルを閉じるときに存在している必要があります。
第3引数のmodeには、_IONBF(unbuffered)、_IOFBF(fully buffered)、_IOLBF(line buffered)を指定できます。これらの値はstdio.hで定義されています。
プログラム 例
#include <stdio.h>
#include <ctype.h>
#define SIZE 1024
int main(int argc, char **argv)
{
FILE *fp_in;
FILE *fp_out;
char in_buff[SIZE]; /* 入力ファイル用バッファ */
char out_buff[SIZE]; /* 出力ファイル用バッファ */
char my_buff[SIZE];
char *p_buff;
int return_code = 0;
if (argc == 3) {
if ((fp_in = fopen(*(argv + 1), 'r')) != NULL) {
if ((fp_out = fopen(*(argv + 2), 'w')) != NULL) {
/* バッファリング方法を設定 */
setvbuf(fp_in, in_buff, _IOLBF, SIZE);
setvbuf(fp_out, out_buff, _IOLBF, SIZE);
while(fgets(my_buff, SIZE, fp_in) != NULL) {
/* 英小文字を英大文字に変換 */
for (p_buff = my_buff; *p_buff; ++p_buff) {
*p_buff = toupper(*p_buff);
}
fputs(my_buff, fp_out);
}
fclose(fp_in);
fclose(fp_out);
}
else {
printf('出力ファイルのオープンに失敗しました\n');
fclose(fp_in);
return_code = 1;
}
}
else {
printf('入力ファイルのオープンに失敗しました\n');
return_code = 1;
}
}
else {
printf('実行時引数の数が不当です\n');
return_code = 2;
}
return return_code;
}
例の実行結果
$ cat temp_1.txt Hello World!!. Bye. $ $ ./setvbuf.exe temp_1.txt temp_8.txt $ $ cat temp_8.txt HELLO WORLD!!. BYE. $